/**********************************************
*  Classes:   BoundingBox
*  Desc:      Defines the bounding box of a 3d 
*             model
*  Author:    Vaios Kalpias-Ilias (C) 2008-2009
***********************************************/

#ifndef BOUNDINGBOX_H
#define BOUNDINGBOX_H

#include "Vector.h"
#include "Quaternion.h"


class Frustrum3;

class BoundingBox
{
public:

	BoundingBox();

	BoundingBox(float _maxX,
		        float _minX,
				float _maxY,
		        float _minY,
				float _maxZ,
		        float _minZ				
				);

	BoundingBox(const BoundingBox& b);

	~BoundingBox();


	// translate and rotate the box
	void Move(const mth::Vector3& pos, 
		const mth::Quaternion rot);

	// grow the box if it is bigger than b
	void Grow(const BoundingBox& b);

	// scales the box
	void Scale(const mth::Vector3& s);

	// tests if the box is inside a view frustrum
	bool IsInside(const Frustrum3& f) const;


	void Update(const mth::Vector3& pos, 
		        const mth::Matrix33& rot,
				float scale);

	float maxX;
	float minX;
	float maxY;
	float minY;
	float maxZ;
	float minZ;


private:

	// near plane upper left
	mth::Vector3 NUL;
	// near plane upper right
	mth::Vector3 NUR;
	// near plane down left
	mth::Vector3 NDL;
	// near plane down right
	mth::Vector3 NDR;
	// far plane upper left
	mth::Vector3 FUL;
	// far plane upper right
	mth::Vector3 FUR;
	// far plane down left
	mth::Vector3 FDL;
	// far plane down right
	mth::Vector3 FDR;
	

	float Min(float a, float b)
	{
		return a > b ? b : a;
	}

	float Max(float a, float b)
	{
		return a > b ? a : b;
	}

	void UpdateBounds(const mth::Vector3& v)
	{
		maxX = Max(maxX, v.x);
		maxY = Max(maxY, v.y);
		maxZ = Max(maxZ, v.z);
		minX = Min(minX, v.x);
		minY = Min(minY, v.y);
		minZ = Min(minZ, v.z);
	}
	
	void UpdateVectors();


	
};

#endif